# encoding:utf-8
'''
@author : xaing
@time : 2019/4/4 11:26
@地址 : 广州
@作用 : 获取系统状态
@结果 :
'''

import psutil
from psutil import AccessDenied
from version1 import common
from version1 import logUtils as log
import socket
import time



def getOsStatus():
    '''
    获取系统相关的状态信息
    :return:
    '''
    common.printStr("CPU逻辑数量: ", psutil.cpu_count())
    common.printStr("CPU物理核心: ", psutil.cpu_count(logical=False), " (2说明是双核超线程, 4则是4核非超线程)")
    common.printStr("CPU的用户／系统／空闲时间: ", psutil.cpu_times())
    common.printStr("CPU使用率: ", psutil.cpu_percent(interval=1, percpu=True))

    # 返回的是字节为单位的整数
    common.printStr("物理内存: ", psutil.virtual_memory())
    common.printStr("交换内存: ", psutil.swap_memory())

    common.printStr("磁盘分区信息: ", psutil.disk_partitions())
    common.printStr("磁盘'/'的使用情况: ", psutil.disk_usage('/'))
    common.printStr("磁盘IO: ", psutil.disk_io_counters())

    try:
        common.printStr("网络读写字节／包的个数: ", psutil.net_io_counters())
        common.printStr("网络接口信息: ", psutil.net_if_addrs())
        common.printStr("网络接口状态: ", psutil.net_if_stats())
        common.printStr("网络连接信息: ", psutil.net_connections())
    except AccessDenied:
        common.printStr("获取网络连接信息需要root权限,请退出Python交互环境，用sudo重新启动")

    common.printStr("所有进程ID: ", psutil.pids())




def getPidStatus(pid):
    '''
    获取指定pid的信息
    :param pid: pid
    :return:
    '''
    try:
        common.printStr("指定PID名: ", psutil.Process(pid).name())
        # common.printStr("指定进程exe路径: ", psutil.Process(pid).exe())
        # common.printStr("进程工作目录: ", psutil.Process(pid).cwd())
        # common.printStr("进程启动的命令行: ", psutil.Process(pid).cmdline())
        common.printStr("父进程ID: ", psutil.Process(pid).ppid())
        common.printStr("父进程: ", psutil.Process(pid).parent())
        common.printStr("子进程列表: ", psutil.Process(pid).children())
        # common.printStr("进程状态: ", psutil.Process(pid).running())
        common.printStr("进程用户名: ", psutil.Process(pid).username())
        common.printStr("进程创建时间: ", psutil.Process(pid).create_time())
        common.printStr("进程终端: ", psutil.Process(pid).terminal())
        common.printStr("进程使用的CPU时间: ", psutil.Process(pid).cpu_times())
        common.printStr("进程使用的内存: ", psutil.Process(pid).memory_info())
        common.printStr("进程打开的文件: ", psutil.Process(pid).open_files())
        common.printStr("进程相关网络连接: ", psutil.Process(pid).connections())
        common.printStr("进程的线程数量: ", psutil.Process(pid).num_threads())
        common.printStr("所有线程信息: ", psutil.Process(pid).threads())
        common.printStr("进程环境变量: ", psutil.Process(pid).environ())
        common.printStr("结束进程: ", psutil.Process(pid).terminate())
    except Exception as e:
        log.outErrorLog("无法获取pid：", pid, " 信息，错误原因:", e)



def checkPort(ip, port):
    '''
    输入IP和端口号，扫描判断端口是否占用
    :param ip: IP地址  192.168.0.1
    :param port: 端口是数字类型  80
    :return: True 被占用 false 没被占用
    '''
    try:
        if port >= 65535:
            print(u'端口扫描结束')
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        result = s.connect_ex((ip, port))
        if result == 0:
            print(ip, u':', port, u'端口已占用')
            return True
        else:
            return False

    except Exception as e:
        log.outErrorLog("端口扫描异常，错误信息:", e)


def ip_scan(ip):
    '''
    输入IP，扫描IP的0-65534端口情况，该方法不建议调用，耗时非常久，应该使用多线程来解决
    :param ip: IP地址
    :return: 不会有返回信息
    '''
    try:
        print(u'开始扫描 %s' % ip)
        start_time = time.time()
        for i in range(0, 65534):
            result = checkPort(ip, int(i))

        print(u'扫描端口完成，总共用时：%.2f' % (time.time() - start_time))
    except:
        print(u'扫描ip出错')


